﻿using STHPMS1.BLL.B_Core;
using STHPMS1.ICore.I_BLL.Bus;
using STHPMS1.ICore.I_Entity.Info;
using STHPMS1.ICore.I_Entity.Stmpms1;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using STHPMS1.Common.C_Entity.Stmpms1;
using System.Linq;
using System.Collections;
using STHPMS1.ICore;
using STHPMS1.ICore.I_Serv;
using STHPMS1.ICore.I_DAL;
using System.Data;

namespace STHPMS1.BLL.B_Bus
{
    public class Dr_Repair_MidBus : BllBase, IDr_Repair_MidBill
    {
        public void Save<T>(T entity)
            where T : class ,IDr_Repair_Mid
        { 
		this.Scene.Dal.Sthpms1.Save(entity);
        }

        public void Remove(IDr_Repair_Mid entity)
        {
            this.Scene.Dal.Sthpms1.DeleteById<Dr_Repair_Mid>(entity.Id);
        }

        public IEnumerable<T> Get<T>(Expression<Func<T, bool>> predicate, IPagingInfo info)
            where T : class, IDr_Repair_Mid
        {
            return this.Scene.Dal.Sthpms1.Select<T>(predicate, info).OrderBy(p=>p.Beginmp);
        }


        /// <summary>
        /// 添加中修数据
        /// </summary>
        /// <param name="anniname"></param>
        /// <param name="analy_year"></param>
        public void Insert(string anniname, string analy_year)
        {
            IKeyGenrateService serv = MyApp.Locator.GetInstance<IKeyGenrateService>();
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            dao.Delete<Dr_Repair_Mid>(p => p.Anni_Name == anniname && p.Analy_Year == analy_year);

             ///获取中修路段
            Expression<Func<Dn_Divi_Planning, bool>> exp = null;
            if (analy_year != null && analy_year.ToString().Length > 0 && analy_year != null && analy_year.ToString().Length > 0)
                exp = pre => pre.Anni_Name == anniname.ToString() && pre.Divi_Time == analy_year.ToString() && pre.Segid_Main == 12002;
            List<Dn_Divi_Planning> list = this.Scene.Bll.Dn_Divi_Planning.Get<Dn_Divi_Planning>(exp, null).ToList<Dn_Divi_Planning>();
            foreach (Dn_Divi_Planning info in list)
            {
                Dr_Repair_Mid dr_info = new Dr_Repair_Mid();
                dr_info.Id = serv.NewGuid(); //ID
                dr_info.Anni_Name = info.Anni_Name; //资金模型名称
                dr_info.Analy_Year = analy_year; //分析年度
                dr_info.RoadnetId = info.RoadnetId; //路网ID
                dr_info.MainSegid = info.Mainsegid; //决策路段
                dr_info.Rdwayid = info.Rdwayid; //路线编号
                dr_info.Beginmp = info.Beginmp; //起点桩号
                dr_info.Endmp = info.Endmp; //终点桩号

                IB_Invntory ib_invntory = this.Scene.Bll.Dp_Dailymain_Cost.GetB_Invntory(info.Mainsegid); //基础路段信息
                int? Rdclass_Dictid = ib_invntory.Rdclass_Dictid; //技术等级
                int? admdiv=ib_invntory.Admdiv; //行政区域

                #region 厚度设计
                if (info.Segid_Elamod != null && info.Segid_Elamod>=0) // 回弹模量是否有值
                {
                    //根据技术等级和路面类型 确定设计年限
                    Dm_Default_Rating dm_dafault_rating = dao.Single<Dm_Default_Rating>(p => p.Rdclass_Dictid == Rdclass_Dictid);

                    //dm_dafault_rating.Year_Asp;

                    //根据设计年限 计算设计年限累计当量轴次
                    Dn_Divi_Result result = dao.Single<Dn_Divi_Result>(p => p.Mainsegid == info.Mainsegid);
                    //double  IDm_ModelgroupBill.GetEaslByModel(IDn_Divi_Result result, analy_year, dm_dafault_rating.Year_Asp);


                    //double EASL = 85;

                    //double EASL = this.Scene.Bll.Dm_Modelgroup.GetEaslByModel(result,Convert.ToInt32(analy_year),Convert.ToDouble(dm_dafault_rating.Year_Asp));
                    double EASL = this.Scene.Bll.Dm_Modelgroup.GetEaslByModel(result,DateTime.Now.Year+Convert.ToInt32(dm_dafault_rating.Year_Asp));

                    //中修厚度方法1推荐表  
                    Dr_Thick1_Mid dr_thick1_mid = dao.Single<Dr_Thick1_Mid>(p => (p.Rdclass_Dictid == Rdclass_Dictid) && p.Easl_Max > EASL && p.Easl_Min <= EASL && p.Mpa_Max > info.Segid_Elamod && p.Mpa_Min <= info.Segid_Elamod);

                    dr_info.Up_Thick = dr_thick1_mid.Pav_Top; //上面层厚度
                    dr_info.Mid_Thick = dr_thick1_mid.Pav_Middle; //中面层厚度

                    //dr_info.Up_Thick = 4; //上面层厚度
                    //dr_info.Mid_Thick = 5; //中面层厚度


                }
                else   //根据PCI值进行厚度设计
                {
                    //中修厚度方法2推荐表
                    Dr_Thick2_Mid dr_thick2_mid = dao.Single<Dr_Thick2_Mid>(p => (p.Rdclass_Dictid == Rdclass_Dictid) && p.Pci_Max>info.Pci && p.Pci_Min<=info.Pci);
                    //dr_info.Up_Thick = dr_thick2_mid.Pav_Top; //上面层厚度
                    //dr_info.Mid_Thick = dr_thick2_mid.Pav_Middle; //中面层厚度

                    dr_info.Up_Thick = 4; //上面层厚度
                    dr_info.Mid_Thick = 5; //中面层厚度
                }
                #endregion

                #region 确定材料

                //行政区域转换为市级
                string stradmdiv = admdiv.ToString().Substring(0, 4) + "00";
                //大中修温度推荐表
                Dr_Temperature dr_temperature= dao.Single<Dr_Temperature>(p => p.Regioncode == Convert.ToInt32(stradmdiv));
                //大中修材料推荐表
                Dr_Stru_Recomm dr_stru_recomm = dao.Single<Dr_Stru_Recomm>(p => p.Pave_Type == 12002 && p.Rdclass_Dictid == Rdclass_Dictid && p.Hightemerate_Max > dr_temperature.Max && p.Hightemerate_Min <= dr_temperature.Max && p.Lowtemerate_Max > dr_temperature.Min && p.Lowtemerate_Min <= dr_temperature.Min);

                dr_info.Up_StruName = dr_stru_recomm.Pav_Top;  //上面层材料
                dr_info.Mid_StruName = dr_stru_recomm.Pav_Middle; //中面层材料

                #endregion


                #region 计算总费用

                //计算路段面积
                double? Area = (info.Endmp - info.Beginmp) * ib_invntory.Surfwidth;  //平方米
                //大中修材料价格表
                Dr_Stru_Mate dr_stru_mateInfo1= dao.Single<Dr_Stru_Mate>(p => p.Stru_Name == dr_info.Up_StruName); //上面层材料单价
                Dr_Stru_Mate dr_stru_mateInfo2 = dao.Single<Dr_Stru_Mate>(p => p.Stru_Name == dr_info.Mid_StruName); //中面层材料单价

                double? cost_up = dr_stru_mateInfo1.Stru_Price * Area * dr_info.Up_Thick;  //上面层总价
                double? cost_mid = dr_stru_mateInfo2.Stru_Price * Area * dr_info.Mid_Thick; //中面层总价

                dr_info.Cost = (cost_up + cost_mid)/10000;
                //保存到中修结果表
                dao.Save<Dr_Repair_Mid>(dr_info);
                //更新到路网决策路段表
                dao.Update<Dn_Divi_Planning>(new { Project_Id = dr_info.Id, Project_Name = "", Cost = dr_info.Cost, Main_Year = analy_year }, p => p.Anni_Name == anniname && p.Divi_Time == analy_year && p.Mainsegid == info.Mainsegid);
                #endregion


            }
        }




        /// <summary>
        /// 决策路段的弯沉检测点总和
        /// </summary>
        /// <param name="segid">决策路段</param>
        /// <returns></returns>
        public int Sgeid_RepdeflCount(string segid)
        {
            return this.Scene.Dal.Sthpms1.Dr_Repair_Mid.Sgeid_RepdeflCount(segid);
        }

        /// <summary>
        /// 决策路段的平均弯沉值
        /// </summary>
        /// <param name="sgeid">决策路段</param>
        /// <returns></returns>
        public double Sgeid_AvageRepdefl(string segid)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            return dao.Dr_Repair_Mid.Sgeid_AvageRepdefl(segid);
            //return this.Scene.Dal.Sthpms1.Dr_Repair_Mid.Sgeid_AvageRepdefl(segid);
        }

        /// <summary>
        /// 决策路段弯沉标准差  公式上部分
        /// </summary>
        /// <param name="segid">决策路段</param>
        /// <param name="avagerepdefl">决策路段的平均弯沉值</param>
        /// <returns></returns>
        public double Segid_RepdeflCha(string segid, double avagerepdefl)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;
            return dao.Dr_Repair_Mid.Segid_RepdeflCha(segid, avagerepdefl);
            //return this.Scene.Dal.Sthpms1.Dr_Repair_Mid.Segid_RepdeflCha(segid,avagerepdefl);
        }


        /// <summary>
        /// 决策路段的计算弯沉值
        /// </summary>
        /// <returns></returns>
        public double GetRepdefl(string segid)
        {


            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;

            int RepdeflCount= Sgeid_RepdeflCount(segid);

            double AvageRepdefl = Sgeid_AvageRepdefl(segid); //决策路段的平均弯沉值

            int? rd = dao.Scene.Bll.Dp_Dailymain_Cost.GetB_Invntory(segid).Rdclass_Dictid; //公路等级

            double RepdeflCha = Segid_RepdeflCha(segid, AvageRepdefl); //决策路段弯沉标准差  公式上部分

            double S = Math.Pow(RepdeflCha / (RepdeflCount - 1),0.5);


            double L=0;
            if (rd == 160 || rd == 161)
            {
                L = AvageRepdefl + 1.645 * S;
            }
            else
            {
                L = AvageRepdefl + 5 * S;
            }
            
            return L;

        }

        /// <summary>
        /// 决策路段原路面当量回弹模量
        /// </summary>
        /// <param name="segid"></param>
        /// <returns></returns>
        public double GetELAMOD(string segid)
        {
            double L = GetRepdefl(segid);
            return 1000 * ((2 * 0.7 * 10.65) / L) * 1.1 * 1;
        }

    }
}
